package com.yuyou.fn.educational.service.impl;

import cn.beststudy.member.*;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.Student;
import com.yuyou.fn.educational.service.ICustomerBindStudentService;
import com.yuyou.fn.educational.service.ICustomerUserService;
import com.yuyou.fn.educational.service.IStudentService;
import com.yuyou.fn.platform.entity.CustomerUser;
import com.yuyou.fn.platform.entity.Oauth;
import com.yuyou.fn.platform.mapper.CustomerUserMapper;
import com.yuyou.fn.platform.service.IOauthService;
import com.zy.otuc.AuthHandler;
import com.zy.otuc.Member;
import com.zy.otuc.UCOutWebService;
import com.zy.otuc.UserWebServiceService;
import io.jsonwebtoken.ExpiredJwtException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;


/**
 *
 * CustomerUser 表数据服务层接口实现类
 *
 */
@Service
public class CustomerUserServiceImpl extends SuperServiceImpl<CustomerUserMapper, CustomerUser,Long> implements ICustomerUserService {

    private final static Pattern PHONE_PATTERN = Pattern.compile("1\\d{10}") ;

    @Resource
    private IOauthService oauthService ;

    @Resource
    private IStudentService studentService;

    @Resource
    private ICustomerBindStudentService customerBindStudentService;

    @Resource
    private ISiteConfigService siteConfigService ;

    private volatile UCOutWebService ucOutWebService ;

    private volatile RegistrationServiceSoap registrationService ;

    private UCOutWebService getUCOutWebService() {

        if(ucOutWebService != null ){
            return ucOutWebService ;
        }
        synchronized (this){
            if(ucOutWebService != null ){
                return ucOutWebService ;
            }
            UserWebServiceService userWebServiceService = new UserWebServiceService(Urls.create(siteConfigService.getConfigValueFromCache("uc_webservice_url")));
            userWebServiceService.setHandlerResolver((portInfo)->Arrays.asList(new AuthHandler()));
            ucOutWebService  = userWebServiceService.getUserWebServicePort();
        }
        return ucOutWebService;
    }

    private RegistrationServiceSoap getRegistrationService() {

        if(registrationService != null ){
            return registrationService ;
        }
        synchronized (this){
            registrationService =  new RegistrationService(Urls.create(siteConfigService.getConfigValueFromCache("member_webservice_url"))).getRegistrationServiceSoap();
        }
        return registrationService;
    }

    @Transactional
    @Override
    public CustomerUser loginFormWx(String openId, String nickname , String sex, String province, String city, String avatar) {
        Oauth oauth = oauthService.findByRoleOpenId(1, openId);
        if(oauth == null ){
            return null ;
        }
        CustomerUser customerUser = findById(oauth.getUserId());
        setCustomerUserInfo(nickname, sex, province, city, avatar , customerUser);
        Threads.dispatch(()->{
            customerUser.setUpdateTime(TimeUtils.now());
            updateSelectiveById(customerUser);
        });
        return customerUser;

    }

    @Override
    public CustomerUser wxBindPhoneNo(String phoneNo, String openId, String nickname, String sex, String province, String city, String avatar) {
        CustomerUser customerUser = createCustomerUserIfNeed(phoneNo,null , null );
        try{
            oauthService.saveOauth(1 ,customerUser.getUserId(),openId,1 ) ;
        }catch (Exception e ){
            if(e.getMessage().contains("un_open_id_role")){
                oauthService.updateUserId(customerUser.getUserId(),openId,1);
            }
        }

        setCustomerUserInfo(nickname, sex, province, city, avatar , customerUser);
        Threads.dispatch(()->{
            customerUser.setUpdateTime(TimeUtils.now());
            updateSelectiveById(customerUser);
        });
        return customerUser;
    }


    private void setCustomerUserInfo(String nickname, String sex, String province, String city, String avatar, CustomerUser customerUser) {
        if(StringUtils.isNotEmpty(avatar)){
            customerUser.setAvatarUrl(avatar);
        }

        if(StringUtils.isNotEmpty(province)){
            StringBuilder sb  = new StringBuilder() ;
            sb.append(province);
            if(StringUtils.isNotEmpty(city)){
                sb.append(" ").append(city);
            }
            customerUser.setLocation(sb.toString());
        }

        if(StringUtils.isNotEmpty(sex)){
            customerUser.setSex("男".equals(sex) ? 1 : 2);
        }

        if(StringUtils.isNotEmpty(nickname)){
            customerUser.setNickname(nickname);
        }
    }

    @Override
    public void updatePersonMessage(CustomerUser customerUser) {
        if(StringUtils.isNoneEmpty(customerUser.getPassword())){
            customerUser.setPassword(DigestUtils.md5Hex(customerUser.getPassword() ));
        }
        checkCustomerUser(customerUser);
        updateSelectiveById(customerUser);
    }

    private void checkCustomerUser(CustomerUser customerUser) {

        if(StringUtils.isNoneEmpty(customerUser.getUsername())){
            Example<CustomerUser> example = CustomerUser.createExample();
            example.createCriteria().andEqualTo("username",customerUser.getUsername());
            if(countByExample(example) > 0 ){
                throw new BusException("用户名已经被注册");
            }
        }

        if(StringUtils.isNoneEmpty(customerUser.getPhoneNo())){
            Example<CustomerUser> example = CustomerUser.createExample();
            example.createCriteria().andEqualTo("phoneNo",customerUser.getPhoneNo());
            if(countByExample(example) > 0 ){
                throw new BusException("手机号码已经被注册");
            }
        }

    }

    @Override
    public CustomerUser findCustomerUserByPhoneNo(String phoneNo) {
        Example<CustomerUser> example = CustomerUser.createExample();
        example.createCriteria().andEqualTo("phoneNo",phoneNo.trim());
        return findOneByExample(example);
    }

    @Override
    public CustomerUser registerCustomerUserPhoneNo( String phoneNo , String password , String avatarUrl, Integer sex, String location) {

        Validate.notNull(password,"密码不能为空");
        Validate.notNull(phoneNo,"电话号码不能为空");

        if(!PHONE_PATTERN.matcher(phoneNo).matches()){
            throw new BusException("手机号码格式不正确");
        }

        CustomerUser customerUser = new CustomerUser();
        if(StringUtils.isNotEmpty(avatarUrl)){
            customerUser.setAvatarUrl(avatarUrl);
        }

        if(StringUtils.isNotEmpty(location)){
            customerUser.setLocation(location);
        }

        if(sex != null){
            customerUser.setSex(sex);
        }else{
            customerUser.setSex(0);
        }
        customerUser.setUsername("pn_" + Base64.encodeBase64URLSafeString(String.valueOf( IdWorker.getId() ).getBytes() ) );
        customerUser.setPhoneNo(phoneNo);
        customerUser.setPassword(DigestUtils.md5Hex(password ));
        customerUser.setCreateTime(TimeUtils.now());
        customerUser.setUpdateTime(TimeUtils.now());
        insertSelective(customerUser);
        return customerUser ;
    }

    @Override
    public CustomerUser loginByPhoneNo(String phoneNo) {
        CustomerUser customerUser = findCustomerUserByPhoneNo(phoneNo);
        if(customerUser != null ){
            return customerUser ;
        }
        return registerCustomerUserPhoneNo(phoneNo,"yuyou100",null , null , null );
    }

    @Override
    @Transactional
    public CustomerUser createCustomerUserIfNeed(String phoneNo , String ppId , String memberId ) {

        if(!PHONE_PATTERN.matcher(phoneNo).matches()){
            throw new BusException("手机号码格式不正确");
        }

        memberId = StringUtils.isEmpty(memberId) ? syncCustomerUserToMemberCenter(phoneNo) : memberId ;

        CustomerUser customerUser;
        customerUser = this.findCustomerUserByPhoneNo(phoneNo);
        if(null == customerUser){
            customerUser = new CustomerUser();
            customerUser.setUsername("pn_" + Base64.encodeBase64URLSafeString(String.valueOf( IdWorker.getId() ).getBytes() )  );
            customerUser.setPassword(DigestUtils.md5Hex("654321"));
            customerUser.setPhoneNo(phoneNo.trim());
            customerUser.setPpId(ppId);
            customerUser.setMemberId(memberId);
            customerUser.setCreateTime(TimeUtils.now());
            customerUser.setUpdateTime(TimeUtils.now());
            this.insertSelective(customerUser);
            customerUser.setIfNew(1);
            Long userId = customerUser.getUserId();
            Threads.dispatch(()->customerBindStudentService.autoBindStudent(userId,phoneNo));
        }else {
            customerUser.setIfNew(0);
            customerUser.setPpId(ppId);
            customerUser.setMemberId(memberId);
            customerUser.setUpdateTime(TimeUtils.now());
            updateSelectiveById(customerUser);
        }
        return customerUser;
    }

    @Override
    public CustomerUser loginFormUC(String ticket) {

        String ppId = null ;
        try{
            ppId = (String) JWTToken.parse(ticket,"2019").get("ppId");
        }catch (ExpiredJwtException e){
            throw new BusException("ticket过期");
        }

        /*Example<CustomerUser> example = CustomerUser.createExample();
        example.createCriteria().andEqualTo("ppId" , ppId );

        CustomerUser customerUser = findOneByExample(example);

        if(customerUser != null ){
            return customerUser;
        }*/


        Member memberInfo = getUCOutWebService().getMemberInfo(Integer.parseInt(ppId),23 );
        return createCustomerUserIfNeed(memberInfo.getPhoneNumber(), ppId, memberInfo.getMemberId());
    }

    @Override
    public String syncCustomerUserToMemberCenter(String phoneNo) {

        MatchParentInfoTXZ matchParentInfo = getRegistrationService().matchParentInfoByCellPhoneNumTXZ(phoneNo);
        if(matchParentInfo == null || matchParentInfo.getPAllClientList() == null || matchParentInfo.getPAllClientList().getSrcAllClientDTOTXZ().size() == 0 ){

            XMLGregorianCalendar xmlGregorianCalendar = null;

            xmlGregorianCalendar = TimeUtils.dateToXmlDate(new Date(1970));

            MemberProfileDTO registration = getRegistrationService().registration(18, 2, phoneNo, null, 2, xmlGregorianCalendar );
            return registration.getMemberID() ;
        }else{
            List<SrcAllClientDTOTXZ> list = matchParentInfo.getPAllClientList().getSrcAllClientDTOTXZ();
            SrcAllClientDTO srcAllClientDTO = list.get(list.size() - 1);
            return srcAllClientDTO.getMemberID();
        }

    }


}